using System.Security.Claims;
using System.Text.Json;
using System.Threading.Tasks;
using Identity.Application.Contracts.Requests.Auth;
using Identity.Application.Contracts.Services;
using Identity.Application.Roles.Commands;
using Identity.Application.UserAggregates.Commands;
using Identity.Infrastructure.Entities;
using MediatR;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using OpenIddict.Abstractions;
using OpenIddict.Server;
using OpenIddict.Server.AspNetCore;
using OpenIddict.Validation.AspNetCore;

namespace Identity.HttpAPI.Controllers
{
    [ApiController]
    [Route("api/auth")]
    public class AuthApiController : ControllerBase
    {

        private readonly IMediator _mediator;
        private readonly IOpenIddictServerDispatcher _dispatcher;
        private readonly IUserService _userService;

        public AuthApiController(IMediator mediator, IOpenIddictServerDispatcher dispatcher, IUserService userService)
        {
            _mediator = mediator;
            _dispatcher = dispatcher;
            _userService = userService;


        }

        [HttpPost("login")]
        [AllowAnonymous]
        public async Task<IActionResult> Login([FromBody] LoginUserRequest req)
        {
            var command = new LoginUserCommand(req.userName, req.password);
            var result = await _mediator.Send(command);
            return Ok(result);
        }


        [HttpPost("logout")]
        [Authorize]
        public async Task<IActionResult> Logout()
        {
            // 1. 验证用户身份（可选）
            if (!User.Identity!.IsAuthenticated)
                return Unauthorized();

            // 2. 清理服务器端 session 或其他状态（如果有）

            // 3. 返回注销成功
            return Ok(new { message = "Logged out" });
        }

        [HttpGet("claims")]
        public async Task<IActionResult> Claims()
        {
            var command = new UpdateRoleNameCommand(Guid.Parse("0198c2d6-3081-7711-8d3c-56a5a438c800"), "Admin");
            await _mediator.Send(command);

            return Ok();
    
}

        [HttpPost("refresh-token")]
        [Authorize]
        public async Task<IActionResult> RefreshToken([FromBody] RefreshAccessTokenRequest request)
        {
            if (string.IsNullOrWhiteSpace(request.RefreshToken))
                return BadRequest("Refresh token is required.");

            // 1. 验证 refresh token
            var result = await HttpContext.AuthenticateAsync(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme);
            var principal = result?.Principal;
            if (principal == null)
                return Unauthorized();

            var userId = principal.GetClaim(OpenIddictConstants.Claims.Subject);
            if (userId == null) return Unauthorized();

            var user = await _userService.GetUserByIdAsync(Guid.Parse(userId));
            if (user == null)
                return Unauthorized();

            // 2. 获取最新角色
            var roles = user.Roles;
            // 3. 构造新的 ClaimsPrincipal
            var claims = new List<Claim>
            {
                new Claim(OpenIddictConstants.Claims.Subject, user.Id.ToString()),
                new Claim(OpenIddictConstants.Claims.Name, user.UserName)
            };

            foreach (var role in roles)
            {
                claims.Add(new Claim(ClaimsIdentity.DefaultRoleClaimType, role));
            }

            var identity = new ClaimsIdentity(claims, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);
            var newPrincipal = new ClaimsPrincipal(identity);

            // 设置授权范围与 token 生命周期
            newPrincipal.SetScopes(principal.GetScopes());
            newPrincipal.SetResources("api");
            newPrincipal.SetAccessTokenLifetime(TimeSpan.FromMinutes(60));
            newPrincipal.SetRefreshTokenLifetime(TimeSpan.FromDays(14));

            // 返回新的 access token
            return SignIn(newPrincipal, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);
        }
    }

    // 请求 DTO
    public record RefreshAccessTokenRequest(string RefreshToken);
}